package impl

import (
	"context"
	"fmt"
	"gitee.com/goddesszz/gocommon/myutil"
	"github.com/sirupsen/logrus"
	"monoblog/common"
	"monoblog/common/register"
	"monoblog/config"
	"monoblog/domain/dao"
	"monoblog/domain/model"
	"monoblog/domain/service"
	"time"
)

func init() {
	register.RegisterInstance[service.MomentPublishService]("MomentPublishService", func() service.MomentPublishService {
		return &MomentPublishServiceImpl{
			userRepository:    dao.NewUserRepository(),
			articleRepository: dao.NewArticleRepository(),
			commentRepository: dao.NewCommentRepository(),
		} // 返回唯一实例
	})
}

type MomentPublishServiceImpl struct {
	userRepository    *dao.UserRepository
	articleRepository *dao.ArticleRepository
	commentRepository *dao.CommentRepository
}

func (s *MomentPublishServiceImpl) PublishWithBlog(ctx context.Context, opUserId string, blogId string) error {
	blog, err2 := s.articleRepository.FindLiteByID(blogId)
	if err2 != nil {
		logrus.Errorf("[aid: %s] FindLiteByID 时出错. blogId=%s  err = %v", ctx.Value("aid"), blogId, err2.Error())
		return err2
	}
	// 构造通知数据
	moment := &model.Moment{
		Receiver: blog.AuthorId, // 通知接收用户
		Topic:    model.Moment_Blog,
		//ContentFormat: fmt.Sprintf("我发布了新文章《%s》", blog.Title),
		Content: fmt.Sprintf("我发布了新文章<a href='/blog/%s' target='_blank' class='text-primary underline'>《%s》</a>", blogId, blog.Title),

		TargetId:   blogId, // 关联目标ID（如文章ID、评论ID等）
		CreateTime: time.Now(),
	}

	// 发布到Redis通知频道
	err := config.GetRedisClient().Publish(
		context.Background(),
		common.REDIS_KEY_MOMENT_CHANNEL,
		myutil.JsonToString(moment),
	).Err()
	if err != nil {
		logrus.Errorf("[aid: %s] 发布通知数据到Redis失败. err = %v", ctx.Value("aid"), err)
	}
	return err
}

func (s *MomentPublishServiceImpl) PublishWithLike(ctx context.Context, opUserId string, blogId string) error {
	opUser, err3 := s.userRepository.FindByUserId(opUserId)
	if err3 != nil {
		logrus.Errorf("[aid: %s] FindByUserId 时出错. err = %v", ctx.Value("aid"), err3.Error())
		return err3
	}

	blog, err2 := s.articleRepository.FindLiteByID(blogId)
	if err2 != nil {
		logrus.Errorf("[aid: %s] FindLiteByID 时出错. err = %v", ctx.Value("aid"), err2.Error())
		return err2
	}
	// 构造通知数据
	moment := &model.Moment{
		Receiver: blog.AuthorId, // 通知接收用户
		Topic:    model.Moment_Like,
		//ContentFormat:  fmt.Sprintf("您的文章《%s》被用户%s 点赞\U0001FA77了", blog.Title, opUser.Nickname),
		Content: fmt.Sprintf("您的文章<a href='/blog/%s' target='_blank' class='text-primary underline'>《%s》</a>被用户 <a href='/user/%s' target='_blank' class='text-primary underline'>%s</a> 点赞\U0001FA77了", blogId, blog.Title, opUser.Username, opUser.Nickname),

		TargetId: blogId, // 关联目标ID（如文章ID、评论ID等）

		CreateTime: time.Now(),
	}

	// 发布到Redis通知频道
	err := config.GetRedisClient().Publish(
		context.Background(),
		common.REDIS_KEY_MOMENT_CHANNEL,
		myutil.JsonToString(moment),
	).Err()
	if err != nil {
		logrus.Errorf("[aid: %s] 发布通知数据到Redis失败. err = %v", ctx.Value("aid"), err)
	}
	return err
}
func (s *MomentPublishServiceImpl) PublishWithFavorite(ctx context.Context, opUserId string, blogId string) error {
	opUser, err3 := s.userRepository.FindByUserId(opUserId)
	if err3 != nil {
		logrus.Errorf("[aid: %s] FindByUserId 时出错. err = %v", ctx.Value("aid"), err3.Error())
		return err3
	}

	blog, err2 := s.articleRepository.FindLiteByID(blogId)
	if err2 != nil {
		logrus.Errorf("[aid: %s] FindLiteByID 时出错. err = %v", ctx.Value("aid"), err2.Error())
		return err2
	}
	// 构造通知数据
	moment := &model.Moment{
		Receiver: blog.AuthorId, // 通知接收用户
		Topic:    model.Moment_Favorite,
		//ContentFormat:  fmt.Sprintf("您的文章《%s》被用户%s 收藏了", blog.Title, opUser.Nickname),
		Content: fmt.Sprintf("您的文章<a href='/blog/%s' target='_blank' class='text-primary underline'>《%s》</a>被用户 <a href='/user/%s' target='_blank' class='text-primary underline'>%s</a> 收藏了", blogId, blog.Title, opUser.Username, opUser.Nickname),

		TargetId: blogId, // 关联目标ID（如文章ID、评论ID等）

		CreateTime: time.Now(),
	}

	// 发布到Redis通知频道
	err := config.GetRedisClient().Publish(
		context.Background(),
		common.REDIS_KEY_MOMENT_CHANNEL,
		myutil.JsonToString(moment),
	).Err()
	if err != nil {
		logrus.Errorf("[aid: %s] 发布moment数据到Redis失败. err = %v", ctx.Value("aid"), err)
	}
	return err
}

func (s *MomentPublishServiceImpl) PublishWithFollow(ctx context.Context, opUserId string, userId string) error {
	opUser, err3 := s.userRepository.FindByUserId(opUserId)
	if err3 != nil {
		logrus.Errorf("[aid: %s] FindByUserId 时出错. err = %v", ctx.Value("aid"), err3.Error())
		return err3
	}

	// 构造通知数据
	moment := &model.Moment{
		Receiver: userId, // 通知接收用户
		Topic:    model.Moment_Follow,
		//ContentFormat:  fmt.Sprintf("您被用户%s 关注了", opUser.Nickname),
		Content: fmt.Sprintf("您被用户 <a href='/user/%s' target='_blank' class='text-primary underline'>%s</a> 关注了", opUser.Username, opUser.Nickname),

		TargetId: userId, // 关联目标ID（如文章ID、评论ID等）

		CreateTime: time.Now(),
	}

	// 发布到Redis通知频道
	err := config.GetRedisClient().Publish(
		context.Background(),
		common.REDIS_KEY_MOMENT_CHANNEL,
		myutil.JsonToString(moment),
	).Err()
	if err != nil {
		logrus.Errorf("[aid: %s] 发布通知数据到Redis失败. err = %v", ctx.Value("aid"), err)
	}
	return err

}

func (s *MomentPublishServiceImpl) PublishWithComment(ctx context.Context, opUserId string, commentId string) error {
	currentComment, err2 := s.commentRepository.FindByID(commentId)
	if err2 != nil {
		logrus.Errorf("[aid: %s] FindByID 时出错. err = %v", ctx.Value("aid"), err2.Error())
		return err2
	}

	blog, err2 := s.articleRepository.FindLiteByID(currentComment.BlogId)
	if err2 != nil {
		logrus.Errorf("[aid: %s] FindLiteByID 时出错. err = %v", ctx.Value("aid"), err2.Error())
		return err2
	}

	var moment *model.Moment

	isFirstLevel := currentComment.RootId == ""

	if isFirstLevel {
		// 构造通知数据
		moment = &model.Moment{
			Receiver: blog.AuthorId, // 通知接收用户
			Topic:    model.Moment_Comment,
			//ContentFormat:  fmt.Sprintf("您的文章《%s》被用户%s 评论了：%s", blog.Title, currentComment.Nickname, currentComment.Content),
			Content: fmt.Sprintf("您在文章<a href='/blog/%s' target='_blank' class='text-primary underline'>《%s》</a>被用户 <a href='/user/%s' target='_blank' class='text-primary underline'>%s</a> 回复了：<span class='bg-blue-50 text-blue-800 px-2 py-1 rounded '>%s</span>", blog.ID, blog.Title, currentComment.UserId, currentComment.Nickname, currentComment.Content),

			TargetId: commentId, // 关联目标ID（评论ID）

			CreateTime: time.Now(),
		}
	} else {
		replyToComment, err2 := s.commentRepository.FindByID(currentComment.ReplyId)
		if err2 != nil {
			logrus.Errorf("[aid: %s] FindByID 时出错. err = %v", ctx.Value("aid"), err2.Error())
			return err2
		}

		// 构造通知数据
		moment = &model.Moment{
			Receiver: replyToComment.UserId, // 通知接收用户
			Topic:    model.Moment_Comment_reply,
			//ContentFormat:  fmt.Sprintf("您在文章《%s》中的评论“%s”被用户%s 回复了：%s", blog.Title, replyToComment.Content, currentComment.Nickname, currentComment.Content),
			Content: fmt.Sprintf("您在文章<a href='/blog/%s' target='_blank' class='text-primary underline'>《%s》</a>中的评论<span class='bg-gray-100 text-gray-600 px-2 py-1 rounded '>%s</span>被用户 <a href='/user/%s' target='_blank' class='text-primary underline'>%s</a> 回复了：<span class='bg-blue-50 text-blue-800 px-2 py-1 rounded '>%s</span>", blog.ID, blog.Title, replyToComment.Content, currentComment.UserId, currentComment.Nickname, currentComment.Content),

			TargetId: commentId, // 关联目标ID（评论ID等）

			CreateTime: time.Now(),
		}
	}

	// 发布到Redis通知频道
	err := config.GetRedisClient().Publish(
		context.Background(),
		common.REDIS_KEY_MOMENT_CHANNEL,
		myutil.JsonToString(moment),
	).Err()
	if err != nil {
		logrus.Errorf("[aid: %s] 发布通知数据到Redis失败. err = %v", ctx.Value("aid"), err)
	}
	return err
}
